"""
SchedulerAI 命令行接口

提供用户友好的命令行界面，支持CSV文件输入和结果输出。
"""

import argparse
import sys
from pathlib import Path
from scheduler_ai import scheduler_service
from scheduler_ai.exceptions import SchedulerError


def print_schedule_summary(result):
    """打印调度结果摘要"""
    if not result.has_schedule:
        return

    summary = result.project_summary
    solver_result = result.solver_result

    print("\n" + "=" * 60)
    print("                    调度优化结果摘要")
    print("=" * 60)

    # 基本信息
    print(f"求解状态: {solver_result.status}")
    if solver_result.status == "OPTIMAL":
        print(">> 已找到最优解")
    elif solver_result.status == "FEASIBLE":
        print(">> 已找到可行解")

    print(f"项目总工期: {summary['makespan']} 天")
    print(f"工序总数: {summary['total_activities']} 个")

    if summary.get("solve_time"):
        print(f"求解时间: {summary['solve_time']:.3f} 秒")

    # 关键路径信息
    if summary.get("critical_path"):
        critical_path_str = " → ".join(map(str, summary["critical_path"]))
        print(f"关键路径: {critical_path_str}")

    # 资源利用率
    if summary.get("resource_utilization"):
        print("\n资源利用率:")
        for resource_type, util_info in summary["resource_utilization"].items():
            print(f"  {resource_type}:")
            print(f"    容量: {util_info['capacity']}")
            print(
                f"    峰值使用: {util_info['max_usage']} ({util_info['max_utilization_percent']:.1f}%)"
            )
            print(
                f"    平均使用: {util_info['avg_usage']} ({util_info['avg_utilization_percent']:.1f}%)"
            )


def print_detailed_schedule(result):
    """打印详细调度表"""
    if not result.has_schedule:
        return

    summary = result.project_summary
    schedule = result.schedule

    # 按开始时间排序活动
    sorted_activities = sorted(
        schedule.values(), key=lambda x: (x["start_time"], x["id"])
    )

    print("\n" + "=" * 85)
    print("                        详细施工调度表")
    print("=" * 85)

    # 表头
    print(
        f"{'ID':<6} {'工序名称':<25} {'工期':<6} {'开始时间':<10} {'结束时间':<10} {'资源需求':<20}"
    )
    print("-" * 85)

    for activity in sorted_activities:
        activity_id = activity["id"]
        name = activity.get("name", f"工序{activity_id}")[:24]  # 限制名称长度
        duration = activity["duration"]
        start_time = activity["start_time"]
        end_time = activity["end_time"]

        # 获取资源需求信息（需要从原始数据获取）
        resource_str = activity.get("resource_info", "")

        print(
            f"{activity_id:<6} {name:<25} {duration:<6} {start_time:<10} {end_time:<10} {resource_str:<20}"
        )

    print("-" * 85)
    print(f"总计: {len(sorted_activities)} 个工序，项目工期: {summary['makespan']} 天")


def save_schedule_to_csv(result, output_path):
    """保存调度结果到CSV文件"""
    import pandas as pd
    
    if not result.has_schedule:
        # 创建空的DataFrame并保存
        df = pd.DataFrame({"错误": ["调度优化失败，无结果可保存"]})
        if result.error:
            df = pd.DataFrame({"错误": [f"错误信息: {result.error}"]})
        df.to_csv(output_path, index=False, encoding='utf-8-sig')
        return

    schedule = result.schedule
    
    # 创建调度结果的DataFrame
    schedule_data = []
    for activity_id, activity in schedule.items():
        schedule_data.append({
            'ID': activity['id'],
            '工序名称': activity.get('name', f'工序{activity_id}'),
            '工期': activity['duration'],
            '开始时间': activity['start_time'],
            '结束时间': activity['end_time'],
            '资源需求': activity.get('resource_info', '')
        })
    
    # 按开始时间排序
    schedule_data.sort(key=lambda x: (x['开始时间'], x['ID']))
    
    # 创建DataFrame
    df = pd.DataFrame(schedule_data)
    
    # 保存为CSV，使用utf-8-sig编码以确保Excel能正确显示中文
    df.to_csv(output_path, index=False, encoding='utf-8-sig')


def save_schedule_to_file(result, output_path):
    """保存调度结果到文件"""
    if not result.has_schedule:
        with open(output_path, "w", encoding="utf-8") as f:
            f.write("调度优化失败，无结果可保存\n")
            if result.error:
                f.write(f"错误信息: {result.error}\n")
        return

    summary = result.project_summary
    solver_result = result.solver_result
    sorted_activities = summary.get("sorted_schedule", [])

    with open(output_path, "w", encoding="utf-8") as f:
        # 写入摘要信息
        f.write("SchedulerAI 调度优化结果\n")
        f.write("=" * 50 + "\n\n")

        f.write(f"求解状态: {solver_result.status}\n")
        f.write(f"项目总工期: {summary['makespan']} 天\n")
        f.write(f"工序总数: {summary['total_activities']} 个\n")

        if summary.get("solve_time"):
            f.write(f"求解时间: {summary['solve_time']:.3f} 秒\n")

        # 关键路径
        if summary.get("critical_path"):
            critical_path_str = " → ".join(map(str, summary["critical_path"]))
            f.write(f"关键路径: {critical_path_str}\n")

        f.write("\n")

        # 资源利用率
        if summary.get("resource_utilization"):
            f.write("资源利用率:\n")
            for resource_type, util_info in summary["resource_utilization"].items():
                f.write(f"  {resource_type}:\n")
                f.write(f"    容量: {util_info['capacity']}\n")
                f.write(
                    f"    峰值使用: {util_info['max_usage']} ({util_info['max_utilization_percent']:.1f}%)\n"
                )
                f.write(
                    f"    平均使用: {util_info['avg_usage']} ({util_info['avg_utilization_percent']:.1f}%)\n"
                )

        f.write("\n")

        # 详细调度表
        schedule = result.schedule
        sorted_activities = sorted(
            schedule.values(), key=lambda x: (x["start_time"], x["id"])
        )

        f.write("详细施工调度表:\n")
        f.write("-" * 85 + "\n")
        f.write(
            f"{'ID':<6} {'工序名称':<25} {'工期':<6} {'开始时间':<10} {'结束时间':<10} {'资源需求':<20}\n"
        )
        f.write("-" * 85 + "\n")

        for activity in sorted_activities:
            activity_id = activity["id"]
            name = activity.get("name", f"工序{activity_id}")[:24]
            duration = activity["duration"]
            start_time = activity["start_time"]
            end_time = activity["end_time"]
            resource_str = activity.get("resource_info", "")

            f.write(
                f"{activity_id:<6} {name:<25} {duration:<6} {start_time:<10} {end_time:<10} {resource_str:<20}\n"
            )

        f.write("-" * 85 + "\n")
        f.write(
            f"总计: {len(sorted_activities)} 个工序，项目工期: {summary['makespan']} 天\n"
        )


def main():
    """主函数"""
    parser = argparse.ArgumentParser(
        description="SchedulerAI - 智能施工进度优化工具",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例用法:
  python main.py --input project.csv
  python main.py -i project.csv -o result.txt
        """,
    )

    parser.add_argument("--input", "-i", required=True, help="输入CSV文件路径")

    parser.add_argument("--output", "-o", help="输出结果文件路径(可选)")

    parser.add_argument(
        "--version", "-v", action="version", version="SchedulerAI 1.0.0"
    )

    args = parser.parse_args()

    try:
        # 验证输入文件存在
        input_path = Path(args.input)
        if not input_path.exists():
            print(f"X 错误: 输入文件不存在: {args.input}")
            print("建议:")
            print("  - 检查文件路径是否正确")
            print("  - 确保文件确实存在于指定位置")
            print("  - 使用绝对路径或相对于当前目录的路径")
            sys.exit(1)

        if not input_path.suffix.lower() == ".csv":
            print(f"! 警告: 输入文件不是CSV格式: {args.input}")
            print("  系统将尝试按CSV格式解析，但可能会失败")

        # 检查文件是否可读
        try:
            with open(input_path, "r", encoding="utf-8") as f:
                f.read(1)  # 尝试读取一个字符
        except PermissionError:
            print(f"X 错误: 没有权限读取文件: {args.input}")
            print("建议:")
            print("  - 检查文件权限设置")
            print("  - 确保当前用户有读取权限")
            sys.exit(1)
        except UnicodeDecodeError:
            print(f"X 错误: 文件编码不支持: {args.input}")
            print("建议:")
            print("  - 确保CSV文件使用UTF-8编码")
            print("  - 或者使用Excel另存为UTF-8格式的CSV")
            sys.exit(1)

        # 验证输出路径（如果指定）
        if args.output:
            output_path = Path(args.output)
            try:
                # 检查输出目录是否存在且可写
                output_dir = output_path.parent
                if not output_dir.exists():
                    print(f"X 错误: 输出目录不存在: {output_dir}")
                    print("建议:")
                    print("  - 创建输出目录")
                    print("  - 或者选择已存在的目录")
                    sys.exit(1)

                # 测试写入权限
                test_file = output_dir / ".test_write_permission"
                try:
                    test_file.touch()
                    test_file.unlink()
                except PermissionError:
                    print(f"X 错误: 没有权限写入输出目录: {output_dir}")
                    print("建议:")
                    print("  - 检查目录权限设置")
                    print("  - 选择有写入权限的目录")
                    sys.exit(1)

            except Exception as e:
                print(f"X 错误: 输出路径验证失败: {e}")
                sys.exit(1)

        print(f">> 正在处理项目文件: {args.input}")
        print(">> 开始调度优化...")

        # 调用调度服务
        result = scheduler_service.create_optimized_schedule(args.input)

        if result.success:
            print(">> 调度优化成功完成!")
            print_schedule_summary(result)
            print_detailed_schedule(result)

            if args.output:
                try:
                    # 根据文件扩展名选择保存格式
                    output_path = Path(args.output)
                    if output_path.suffix.lower() == '.csv':
                        save_schedule_to_csv(result, args.output)
                        print(f">> 结果已保存到CSV文件: {args.output}")
                    else:
                        save_schedule_to_file(result, args.output)
                        print(f">> 结果已保存到: {args.output}")
                except Exception as e:
                    print(f"! 警告: 保存文件失败: {e}")
                    print("  调度结果已在控制台显示，请手动保存")
        else:
            print("X 调度优化失败")
            print(f"错误详情: {result.error}")

            # 提供针对性建议
            error_msg = result.error.lower()
            print("\n>> 建议:")
            if "循环依赖" in error_msg:
                print("  - 检查Predecessors列中的依赖关系")
                print("  - 确保没有工序直接或间接依赖自己")
                print("  - 绘制依赖关系图来识别循环")
            elif "文件" in error_msg or "csv" in error_msg:
                print("  - 检查CSV文件格式是否正确")
                print("  - 确保包含必需的列: ID, Name, Duration, Predecessors")
                print("  - 检查数据类型是否正确（ID和Duration应为数字）")
            elif "资源" in error_msg:
                print("  - 检查资源需求是否超过可用容量")
                print("  - 验证资源列名是否正确")
                print("  - 确保资源需求为正数")
            elif "无解" in error_msg or "infeasible" in error_msg:
                print("  - 检查约束条件是否过于严格")
                print("  - 增加资源容量或调整工序依赖关系")
                print("  - 检查是否有不合理的延时设置")
            else:
                print("  - 检查输入数据的完整性和正确性")
                print("  - 参考用户手册了解正确的数据格式")
                print("  - 如问题持续，请联系技术支持")

            sys.exit(1)

    except SchedulerError as e:
        print(f"X 调度器错误: {e}")
        print("\n>> 这通常是由于数据格式或约束问题导致的")
        print("建议:")
        print("  - 检查CSV文件格式和数据完整性")
        print("  - 验证所有必需列是否存在且数据类型正确")
        sys.exit(2)
    except KeyboardInterrupt:
        print("\n>> 用户中断操作")
        print("调度优化已取消")
        sys.exit(130)  # 标准的SIGINT退出代码
    except FileNotFoundError as e:
        print(f"X 文件未找到: {e}")
        print("建议:")
        print("  - 检查文件路径是否正确")
        print("  - 确保文件存在于指定位置")
        sys.exit(2)
    except PermissionError as e:
        print(f"X 权限错误: {e}")
        print("建议:")
        print("  - 检查文件和目录的访问权限")
        print("  - 以管理员身份运行程序（如果需要）")
        sys.exit(13)  # 权限错误的标准退出代码
    except Exception as e:
        print(f"X 系统错误: {e}")
        print("\n>> 这是一个意外错误，请报告给开发团队")
        print("错误信息:")
        print(f"  类型: {type(e).__name__}")
        print(f"  详情: {str(e)}")
        import traceback

        print("\n调试信息:")
        traceback.print_exc()
        sys.exit(1)


if __name__ == "__main__":
    main()
